home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / inpfiel.exe / INPFIELD.CPP < prev    next >
C/C++ Source or Header  |  1993-01-23  |  5KB  |  177 lines

  1. // inpfield.cpp - generic input line class implementation
  2. //
  3. // Christensen OnLine
  4. //
  5. //$Log: inpfield.cpp $
  6. //Revision 1.4  1993/01/23  14:38:15  matt
  7. //Uploaded to CIS
  8. //
  9. //Revision 1.3  1993/01/23  10:07:18  matt
  10. //Experiments with selectAll
  11. //
  12. //Revision 1.2  1993/01/22  21:28:33  matt
  13. //Name changes, getText routines
  14. //
  15. //Revision 1.1  1993/01/13  20:56:46  matt
  16. //Input field with validation
  17. //
  18. #include <string.h>
  19. #include <stdlib.h>
  20. #include <strstream.h>
  21. #include "inpfield.h"
  22.  
  23. ///////////////////////////////////////////////////////////////////////
  24. // InpField
  25. ///////////////////////////////////////////////////////////////////////
  26. InpField::InpField(
  27. int orgX, int orgY, InpData *theInpData, short aDataLen, const char *aLabel
  28. ) :
  29.    inpData(theInpData), dataLen(aDataLen),
  30.    TGroup(TRect(orgX,orgY,orgX,orgY))
  31. {
  32.    // Find length of label, not including ~ chrs.
  33.    //
  34.    short lablen = 0;
  35.    for (int i=0; *(aLabel+i); i++)
  36.       if (*(aLabel+i) != '~')
  37.          lablen++;
  38.  
  39.    // Now that we know how long the label is, grow the TGroup to a size
  40.    // large enough to accomodate the TLabel and TInputLine (below).
  41.    //
  42.    growTo(lablen + dataLen + 4, 1);
  43.  
  44.    // Create TInputLine member, and TLabel if any provided
  45.    //
  46.    inpLine = new TInputLine(
  47.       TRect(lablen+1, 0, lablen+dataLen+4, 1),
  48.       dataLen+1 // Must add space for NULL - documentation wrong
  49.    );
  50.    insert(inpLine);
  51.    inpLine->setData(inpData->getText(dataLen));
  52.    inpLine->setState(sfSelected,False);
  53.    dataSynced = True;
  54.  
  55.    if (lablen) {
  56.       TLabel *labptr =
  57.          new TLabel(TRect(0, 0, lablen+1, 1), aLabel, inpLine);
  58.       insert(labptr);
  59.    }
  60. }
  61.  
  62. void InpField::handleEvent(TEvent& event)
  63. {
  64.    if (event.what & evKeyboard) {
  65.  
  66.       // Input data object (inpData) no longer corresponds to
  67.       // displayed TInputLine (inpLine). Re-fresh may be needed
  68.       // when focus is lost.
  69.       //
  70.       dataSynced = False;
  71.  
  72.       switch (event.keyDown.charScan.charCode) {
  73.       case '\r':
  74.       case '\t':
  75.  
  76.          // If valid input, assign internal value (inpData) to InpLine
  77.          // input string.  Otherwise, display message box with inpData's
  78.          // supplied error message.
  79.          //
  80.          char buf[InpDataMAXLEN+1];
  81.          inpLine->getData(buf);
  82.          if (inpData->isValid(buf)) {
  83.             *inpData = buf;
  84.          }
  85.          else {
  86.             messageBox(inpData->errMsg(), mfOKButton|mfError);
  87.             clearEvent(event);
  88.          }
  89.          break;
  90.       }
  91.    }
  92.    else if (event.what & evMessage) {
  93.  
  94.       switch (event.message.command) {
  95.  
  96.       case cmReceivedFocus:
  97.  
  98.          // Highlight input line
  99.          //
  100.          if (event.message.infoPtr == inpLine) {
  101.             inpLine->selectAll(True);
  102.             inpLine->setState(sfSelected,True);
  103.          }
  104.          break;
  105.  
  106.       case cmReleasedFocus:
  107.  
  108.          if (event.message.infoPtr == inpLine) {
  109.  
  110.             // If inpLine was edited in any way, reset it to the internally
  111.             // stored value.  If the inpLine entry has not yet been
  112.             // validated (\t or \r key event), then the displayed value
  113.             // will change back to the internally stored value (inpData).
  114.             //
  115.             if (!dataSynced) {
  116.                dataSynced = True;
  117.                inpLine->setData(inpData->getText(dataLen));
  118.             }
  119.             inpLine->selectAll(False);
  120.             inpLine->setState(sfSelected,False);
  121.          }
  122.          break;
  123.  
  124.       }
  125.    }
  126.    TGroup::handleEvent(event);
  127. }
  128.  
  129. TPalette& InpField::getPalette() const
  130. {
  131.    static TPalette palette(cpInpField, sizeof(cpInpField));
  132.    return palette;
  133. }
  134.  
  135. ///////////////////////////////////////////////////////////////////////
  136. // IntInpData
  137. ///////////////////////////////////////////////////////////////////////
  138. char InpData::convBuf[InpDataMAXLEN+1];
  139.  
  140. IntInpData::IntInpData(int initValue, int aMin, int aMax) :
  141.    value(initValue), min(aMin), max(aMax)
  142. {
  143. }
  144. int IntInpData::isValid(char *str)
  145. {
  146.    int val = atoi(str);
  147.    return (val >= min && val <= max);
  148. }
  149. InpData& IntInpData::operator = (char *str)
  150. {
  151.    value = atoi(str);
  152.    return *this;
  153. }
  154. char * IntInpData::getText(short len)
  155. {
  156.    strstream buf(convBuf, InpDataMAXLEN, ios::out);
  157.    buf << value << ends;
  158.  
  159.    int vallen=strlen(convBuf);
  160.    if (len <= InpDataMAXLEN && len >= vallen) {
  161.       for (int i=vallen; i<len; i++) convBuf[i] = ' ';
  162.       convBuf[i] = '\0';
  163.    }
  164.    else {
  165.       messageBox("IntInpData::getText - requested len invalid",
  166.          mfOKButton|mfError);
  167.       strcpy(convBuf,"*");
  168.    }
  169.    return convBuf;
  170. }
  171. const char * IntInpData::errMsg()
  172. {
  173.    strstream buf(convBuf, InpDataMAXLEN, ios::out);
  174.    buf<<"Value must be between "<<min<<" and "<<max<<" inclusive"<<ends;
  175.    return convBuf;
  176. }
  177.